

<template>
  <div style="height: 100%" :class="{ 'light-bg': pattern == '2' }">
    <!-- <div class="interval-tab">
      <span
        @click="
          changeSymbol({
            pair_ca: '0x49D37E82390348780444f40929bF233F72e40Ae6',
          })
        "
        >ETH</span
      >
      <span
        @click="
          changeSymbol({
            pair_ca: '0x7fe382B1C10Fc4bcB5b018701eb6CcC09eDBF83c',
          })
        "
        >USDT</span
      >
      <span @click="refreshTv"> 刷新1 </span>
    </div> -->
    <div>
      <div class="interval-tab">
        <span
          @click="changeInterval('1s')"
          :class="{ active: interval == '1s' }"
          >分时</span
        >
        <span @click="changeInterval('1')" :class="{ active: interval == '1' }"
          >1分</span
        >
        <span @click="changeInterval('5')" :class="{ active: interval == '5' }"
          >5分</span
        >
        <span
          @click="changeInterval('15')"
          :class="{ active: interval == '15' }"
          >15分</span
        >
        <span
          @click="changeInterval('60')"
          :class="{ active: interval == '60' }"
          >1小时</span
        >
        <span
          @click="changeInterval('240')"
          :class="{ active: interval == '240' }"
          >4小时</span
        >
        <span
          @click="changeInterval('720')"
          :class="{ active: interval == '720' }"
          >12小时</span
        >
        <span
          @click="changeInterval('1D')"
          :class="{ active: interval == '1D' }"
          >24小时</span
        >
      </div>
    </div>
    <div class="k-line-area">
      <div id="tv_chart_container" style="height: 100%"></div>
      <div class="loading-indicator" v-show="isLoadingTv">
        <div class="tv-spinner"></div>
      </div>
    </div>
    <div class="study-area">
      <div class="study-area-left">
        <span
          @click="setMainIndicator('MA')"
          :class="{ active: isCreateStudyMain['MA'] }"
          >MA</span
        >
        <span
          @click="setMainIndicator('EMA')"
          :class="{ active: isCreateStudyMain['EMA'] }"
        >
          EMA
        </span>
        <span
          @click="setMainIndicator('BOLL')"
          :class="{ active: isCreateStudyMain['BOLL'] }"
          >BOLL</span
        >
        <span
          @click="setMainIndicator('SAR')"
          :class="{ active: isCreateStudyMain['SAR'] }"
          >SAR</span
        >
      </div>
      |
      <div class="study-area-right">
        <span
          @click="setSubIndicator('VOL')"
          :class="{ active: isCreateStudySub['VOL'] }"
          >VOL</span
        >
        <span
          @click="setSubIndicator('MACD')"
          :class="{ active: isCreateStudySub['MACD'] }"
          >MACD</span
        >
        <span
          @click="setSubIndicator('KDJ')"
          :class="{ active: isCreateStudySub['KDJ'] }"
          >KDJ</span
        >
        <span
          @click="setSubIndicator('BOLL')"
          :class="{ active: isCreateStudySub['BOLL'] }"
          >BOLL</span
        >
        <span
          @click="setSubIndicator('RSI')"
          :class="{ active: isCreateStudySub['RSI'] }"
          >RSI</span
        >
        <span
          @click="setSubIndicator('OBV')"
          :class="{ active: isCreateStudySub['OBV'] }"
          >OBV</span
        >
        <span
          @click="setSubIndicator('TRIX')"
          :class="{ active: isCreateStudySub['TRIX'] }"
          >TRIX</span
        >
      </div>
    </div>
  </div>
</template>
<script>
import { nextTick, onMounted, onUnmounted, reactive, ref } from "vue";
import { useRoute, useRouter } from "vue-router";
import { init, dispose, utils, registerIndicator } from "../utils/echarts";
import * as api from "../api/api_path";
import data from "../api/data";
import { tE } from "../utils/flt";
import config from "../klineStyles";
import { useSocket } from "../utils/socket";
import uTimes from "../utils/times";
const { socket, send, on, off } = useSocket("wss://stream.dexx.ai/stream", {});
export default {
  data() {
    return {
      pattern: this.$route.query.pattern,
      chart: null,
      interval: "15",
      isLoadingTv: false,
      symbolInfo: {
        pair_ca: "0x7fe382B1C10Fc4bcB5b018701eb6CcC09eDBF83c",
        chain_id: "8453",
      },
      isCreateStudyMain: {
        MA: false,
        EMA: false,
        BOLL: false,
        SAR: false,
      },
      isCreateStudySub: {
        BOLL: false,
        VOL: false,
        MACD: false,
        KDJ: false,
        TRIX: false,
        RSI: false,
        OBV: false,
      },
    };
  },
  beforeCreate(){
    debugger
  },
  created() {
    debugger
    window.refreshTv = this.refreshTv;
    window.updateWidget = this.updateWidget;
  },
  mounted() {
    const _this = this;
    this.chart = init("tv_chart_container", {
      styles: {
        grid: config.grid(_this.pattern),
        candle: config.candle(),
        yAxis: config.yAxis(_this.pattern),
        xAxis: config.yAxis(_this.pattern),
        separator: config.separator(_this.pattern),
        indicator: config.indicator(),
      },
      locale: "zh-CN",
      customApi: {
        formatBigNumber: (value) => {
          return tE(value);
        },
      },
    });
    _this.chart.setPriceVolumePrecision({
      pricePrecision: 17,
    });
    socket.on("open", (event) => {});
    socket.on("message", (res) => {
      res = JSON.parse(res);
      if (res && res.action === "connect") {
        _this.socketKlineData();
      }
      if (res && res.data) {
        let data = res.data;
        if (res.channel == "token_kline" && data) {
          let kline = {};
          kline.open = kline.close;
          kline.time = Number(1e3 * data[0].timestamp);
          kline.close = data[0].close_price;
          kline.low = data[0].close_price;
          kline.high = data[0].close_price;
          kline.volume = data[0].volume;
          _this.chart.updateData(kline);
        }
      }
    });
  },
  methods: {
    changeInterval(time) {
      this.interval = time;
      updateWidget({ ...this.symbolInfo, kline_interval: time });
      this.closeSendKline();
      this.socketKlineData();
    },

    changeSymbol(info) {
      this.updateWidget({
        ...this.symbolInfo,
        pair_ca: info.pair_ca,
        chain_id: "8453",
      });
      this.closeSendKline();
      this.socketKlineData();
    },
    async updateWidget(params) {
      let prames = {
        pair_ca: params.pair_ca,
        chain_id: params.chain_id,
        from_timestamp: 1717291443,
        to_timestamp: Math.floor(Date.now() / 1000),
        limit: 100,
        kline_interval: uTimes(this.interval),
      };
      this.symbolInfo = prames;
      this.isLoadingTv = true;
      let klineHisList = await this.getKlineHistoryList(prames);
      this.isLoadingTv = false;
      this.chart.applyNewData(klineHisList, klineHisList.length > 0);
      this.chart.loadMore((timestamp) => {
        this.chart.applyMoreData(
          this.getKlineHistoryList({ ...prames, to_timestamp: timestamp }),
          true
        );
      });
      this.setMainIndicator("MA");
    },
    closeSendKline() {
      socket.send(
        JSON.stringify({
          id: this.symbolInfo.id || "1",
          action: "unsubscribe",
          channel: "token_kline",
          data: {
            chain: this.symbolInfo.chain_id,
          },
        })
      );
    },
    socketKlineData() {
      socket.send(
        JSON.stringify({
          id: "1",
          action: "subscribe",
          channel: "token_kline",
          data: {
            chain: this.symbolInfo.chain_id,
            address: this.symbolInfo.pair_ca,
            interval: uTimes(this.interval),
          },
        })
      );
    },

    // 获取历史数据
    async getKlineHistoryList(params) {
      let res = await api.tvs.quoteHis(params);
      let datas = res.data;
      let bars = [];
      for (let i = 0; i < datas.length; i++) {
        bars.push({
          timestamp: Number(1e3 * datas[i].timestamp),
          open: Number(datas[i].open),
          close: Number(datas[i].close),
          high: Number(datas[i].high),
          low: Number(datas[i].low),
          volume: Number(datas[i].volume),
        });
      }
      return bars;
    },
    //主图指标
    setMainIndicator(name) {
      this.isCreateStudyMain[name] = !this.isCreateStudyMain[name];
      this.chart.createIndicator(name, true, { id: "candle_pane" });
    },

    //副图指标添加
    setSubIndicator(name) {
      this.isCreateStudySub[name] = !this.isCreateStudySub[name];
      this.chart.createIndicator(name);
    },
    refreshTv() {
      this.chart.scrollToRealTime();
    },
  },
  onUnmounted() {
    dispose("chart");
  },
};

//setup
// let chart = null;

// const route = useRoute();
// const pattern = route.query.pattern || 1;
// const { socket, send, on, off } = useSocket("wss://stream.dexx.ai/stream", {});
// const interval = ref("15");
// const isLoadingTv = ref(false);
// const symbolInfo = ref({
//   pair_ca: "0x7fe382B1C10Fc4bcB5b018701eb6CcC09eDBF83c",
//   chain_id: "8453",
// });
// const isCreateStudyMain = reactive({
//   MA: false,
//   EMA: false,
//   BOLL: false,
//   SAR: false,
// });
// const isCreateStudySub = reactive({
//   BOLL: false,
//   VOL: false,
//   MACD: false,
//   KDJ: false,
//   TRIX: false,
//   RSI: false,
//   OBV: false,
// });
// window.updateWidget = updateWidget;
// window.refreshTv = refreshTv;
// onMounted(async () => {
//   chart = init("tv_chart_container", {
//     styles: {
//       grid: config.grid(pattern),
//       candle: config.candle(),
//       yAxis: config.yAxis(pattern),
//       xAxis: config.yAxis(pattern),
//       separator: config.separator(pattern),
//       indicator: config.indicator(),
//     },
//     locale: "zh-CN",
//     customApi: {
//       formatBigNumber: (value) => {
//         return tE(value);
//       },
//     },
//   });
//   chart.setPriceVolumePrecision({
//     pricePrecision: 17,
//   });

//   socket.on("open", (event) => {});
//   socket.on("message", (res) => {
//     res = JSON.parse(res);
//     if (res && res.action === "connect") {
//       socketKlineData();
//     }
//     if (res && res.data) {
//       let data = res.data;
//       if (res.channel == "token_kline" && data) {
//         let kline = {};
//         kline.open = kline.close;
//         kline.time = Number(1e3 * data[0].timestamp);
//         kline.close = data[0].close_price;
//         kline.low = data[0].close_price;
//         kline.high = data[0].close_price;
//         kline.volume = data[0].volume;
//         chart.updateData(kline);
//       }
//     }
//   });
// });
// if (import.meta.env.MODE === "development") {
//   // updateWidget(symbolInfo.value);
// }

// function changeInterval(time) {
//   interval.value = time;
//   updateWidget({ ...symbolInfo.value, kline_interval: time });
//   closeSendKline();
//   socketKlineData();
// }
// function changeSymbol(info) {
//   updateWidget({
//     ...symbolInfo.value,
//     pair_ca: info.pair_ca,
//     chain_id: "8453",
//   });
//   closeSendKline();
//   socketKlineData();
// }
// async function updateWidget(params) {
//   let prames = {
//     pair_ca: params.pair_ca,
//     chain_id: params.chain_id,
//     from_timestamp: 1717291443,
//     to_timestamp: Math.floor(Date.now() / 1000),
//     limit: 100,
//     kline_interval: uTimes(interval.value),
//   };
//   symbolInfo.value = prames;
//   isLoadingTv.value = true;
//   let klineHisList = await getKlineHistoryList(prames);
//   isLoadingTv.value = false;
//   chart.applyNewData(klineHisList, klineHisList.length > 0);
//   chart.loadMore((timestamp) => {
//     chart.applyMoreData(
//       getKlineHistoryList({ ...prames, to_timestamp: timestamp }),
//       true
//     );
//   });
//   setMainIndicator("MA");
// }
// function closeSendKline() {
//   socket.send(
//     JSON.stringify({
//       id: symbolInfo.value.id || "1",
//       action: "unsubscribe",
//       channel: "token_kline",
//       data: {
//         chain: symbolInfo.value.chain_id,
//       },
//     })
//   );
// }
// function socketKlineData() {
//   socket.send(
//     JSON.stringify({
//       id: "1",
//       action: "subscribe",
//       channel: "token_kline",
//       data: {
//         chain: symbolInfo.value.chain_id,
//         address: symbolInfo.value.pair_ca,
//         interval: uTimes(interval.value),
//       },
//     })
//   );
// }

// // 获取历史数据
// async function getKlineHistoryList(params) {
//   let res = await api.tvs.quoteHis(params);
//   let datas = res.data;
//   let bars = [];
//   for (let i = 0; i < datas.length; i++) {
//     bars.push({
//       timestamp: Number(1e3 * datas[i].timestamp),
//       open: Number(datas[i].open),
//       close: Number(datas[i].close),
//       high: Number(datas[i].high),
//       low: Number(datas[i].low),
//       volume: Number(datas[i].volume),
//     });
//   }
//   return bars;
// }
// //主图指标
// function setMainIndicator(name) {
//   isCreateStudyMain[name] = !isCreateStudyMain[name];
//   chart.createIndicator(name, true, { id: "candle_pane" });
// }

// //副图指标添加
// function setSubIndicator(name) {
//   isCreateStudySub[name] = !isCreateStudySub[name];
//   chart.createIndicator(name);
// }
// function refreshTv() {
//   chart.scrollToRealTime();
// }
// onUnmounted(() => {
//   dispose("chart");
// });
</script>
<style lang="less" scoped>
.k-line-area {
  height: calc(100% - 82px);
  position: relative;
}
.study-area,
.interval-tab {
  color: #6d7280;
  height: 40px;
  display: flex;
  align-items: center;
  font-size: 12px;
  overflow: auto;
  white-space: nowrap;
  justify-content: center;
  &::-webkit-scrollbar {
    width: 0px; /* 对于垂直滚动条，设置宽度 */
    height: 0px; /* 对于水平滚动条，设置高度 */
  }
  span {
    display: inline-block;
    padding: 2px 8px 2px 8px;
    line-height: 24px;
    margin-left: 2px;
    text-align: center;
    // min-width: 53px;
    white-space: nowrap;
    border-radius: 6px;
    &:hover {
      cursor: pointer;
    }
    &.active {
      font-weight: bold;
    }
  }
}
.study-area {
  border-top: 1px solid #eee;
  position: fixed;
  left: 0;
  right: 0;
  // top: -20px;
  bottom: 0;
  z-index: 9999;
  background: #fff;

  .study-area-left {
    // width: 164px;
    padding: 0 16px;
    span {
      padding: 2px 0;
      margin-right: 10px;
      color: #a0a6b2;
      &:last-child {
        margin-right: 0;
      }
      // margin-left: 8px;
    }
  }
  .study-area-right {
    width: calc(100% - 186px);
    overflow: auto;
    display: flex;
    margin-left: 8px;
    color: #a0a6b2;
    &::-webkit-scrollbar {
      scrollbar-width: none;
      scrollbar-color: none;
      width: 0; /* 对于垂直滚动条，设置宽度 */
      height: 0; /* 对于水平滚动条，设置高度 */
    }
    span {
      padding: 2px 0;
      margin-right: 8px;
      color: #a0a6b2;
      &:last-child {
        padding-right: 16px;
      }
    }
  }
  span {
    &.active {
      font-weight: normal;
      color: #1b1e26;
    }
  }
}
.interval-tab {
  background: #fff;
  border-bottom: 1px solid #eee;
  span {
    &.active {
      background-color: #f0f3fa;
    }
  }
}

.light-bg {
  background-color: #212530;
  color: #ddd;
  .loading-indicator {
    background-color: rgba(33, 37, 48, 0.4);
  }
  .study-area {
    border-top: 1px solid #323c5d;
    background: #212530;
    span {
      &.active {
        color: #fff;
      }
    }
  }
  .interval-tab {
    border-bottom: 1px solid #323c5d;
    background: #212530;
    span {
      &.active {
        color: #fff;
        font-weight: bold;
        background: #292d3a;
      }
    }
  }
}

.loading-indicator {
  background: rgba(255, 255, 255, 0.4);
  height: 100%;
  left: 0;
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: 100%;
  z-index: 1999;

  .tv-spinner {
    animation: tv-spinner__container-rotate-aLqboHuu 0.9s linear infinite;
    border-bottom: 4px solid #8797a533;
    border-left: 4px solid #8797a533;
    border-radius: 50%;
    border-right: 4px solid #8797a533;
    border-top: 4px solid #8797a533;

    border-left-color: rgba(255, 211, 32, 0.4); // rgba(225, 81, 81, 0.4);
    border-top-color: rgba(255, 211, 32, 0.4);
    height: 50px;
    left: calc(50% - 25px);
    margin: 0 auto;
    position: absolute;
    top: calc(50% - 25px);
    width: 50px;
  }
}

@keyframes tv-spinner__container-rotate-aLqboHuu {
  to {
    transform: rotate(1turn);
  }
}
</style>